/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2023. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

/*!
 * @file ac780x_uart_reg.h
 *
 * @brief Uart access register inline function definition.
 *
 */

#ifndef _AC780X_UART_REG_H
#define _AC780X_UART_REG_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* ===========================================  Includes  =========================================== */
#include "ac780x_uart.h"

/* ============================================  Define  ============================================ */

/* ===========================================  Typedef  ============================================ */

/* ==========================================  Variables  =========================================== */

/* ====================================  Functions declaration  ===================================== */

/* ======================================  Functions define  ======================================== */
/*!
 * @brief Set UART Divisor Latch
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] div: UART divisor data
 * @return  none
 */
__STATIC_INLINE void UART_SetDivisor(UART_Type *UARTx, float div)
{
    uint32_t intDiv = (uint32_t)div;
    uint32_t fracDiv = (uint32_t)((div - intDiv) * 32U);

    UARTx->DIV_L = intDiv & 0xFFU;
    UARTx->DIV_H = (intDiv >> 8UL) & 0xFFU;

    UARTx->DIV_FRAC = fracDiv;
}

/*!
 * @brief Set UART Sample counter
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] sampleCounter: UART Sample counter, value can be 0 to 3
 *                         - UART_SMP_CNT0: baud_rate = APB CLOCK/16/{DLH, DLL}
 *                         - UART_SMP_CNT1: baud_rate = APB CLOCK/8/{DLH, DLL}
 *                         - UART_SMP_CNT2: baud_rate = APB CLOCK/4/{DLH, DLL}
 *                         - UART_SMP_CNT3: baud_rate = APB CLOCK/16/{DLM, DLL}
 * @return none
 */
__STATIC_INLINE void UART_SetSampleCounter(UART_Type *UARTx, UART_SampleCntType sampleCnt)
{
    UARTx->SMP_CNT = (sampleCnt & UART_SMP_CNT_SMP_CNT_Msk);
}

/*!
 * @brief Set UART Guart Time and set Guard enable
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] guardTime: UART GuardTime and Guard enable
 *                       bit[4]:  1: enable  0: disable
 *                       bit[3:0]: GuardTime: 0 to 15
 * @return none
 */
__STATIC_INLINE void UART_SetGuard(UART_Type *UARTx, uint8_t guardTime)
{
    if (guardTime & UART_GUARD_GUARD_EN_Msk)
    {
        UARTx->GUARD |= UART_GUARD_GUARD_EN_Msk;
        MODIFY_REG32(UARTx->GUARD, UART_GUARD_GUARD_CNT_Msk, UART_GUARD_GUARD_CNT_Pos, guardTime);
    }
    else
    {
        UARTx->GUARD &= ~UART_GUARD_GUARD_EN_Msk;
        UARTx->GUARD &= ~UART_GUARD_GUARD_CNT_Msk;
    }
}

/*!
 * @brief Set UART Data Bits Length
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] bits: UART Data Bits length, value can be 5 to 9
 *                         - UART_WORD_LEN_5BIT
 *                         - UART_WORD_LEN_6BIT
 *                         - UART_WORD_LEN_7BIT
 *                         - UART_WORD_LEN_8BIT
 *                         - UART_WORD_LEN_9BIT
 * @return none
 */
__STATIC_INLINE void UART_SetDataBits(UART_Type *UARTx, UART_WordLenType bits)
{
    if ((UART_WORD_LEN_5BIT <= bits) && (bits <= UART_WORD_LEN_8BIT))
    {
        MODIFY_REG32(UARTx->LCR0, UART_LCR0_WLS1_WLS0_Msk, UART_LCR0_WLS1_WLS0_Pos, (bits - 5U));  /* set WLS1_WLS0 */
        UARTx->LCR1 &= ~UART_LCR1_WLS2_Msk;      /* set WLS2 */
    }
    else if (bits == UART_WORD_LEN_9BIT)
    {
        UARTx->LCR0 &= ~UART_LCR0_WLS1_WLS0_Msk;       /* set WLS1_WLS0 */
        UARTx->LCR1 |= UART_LCR1_WLS2_Msk;             /* set WLS2 */
    }
    else
    {
        /* do nothing */
    }
}

/*!
 * @brief Set UART stop bit
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] stopBit: UART StopBit. value can be
 *                         - UART_STOP_2BIT: 2 stop bit
 *                         - UART_STOP_1BIT: 1 stop bit
 * @return none
 */
__STATIC_INLINE void UART_SetStopBit(UART_Type *UARTx, UART_StopBitType stopBit)
{
    MODIFY_REG32(UARTx->LCR0, UART_LCR0_STB_Msk, UART_LCR0_STB_Pos, stopBit);
}

/*!
 * @brief Set UART Inverse the tx output
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] InvTx: UART invTx.
 *                         -ENABLE: inverse tx output
 *                         -DISABLE: don't inverse tx output
 * @return none
 */
__STATIC_INLINE void UART_SetInvTx(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->LCR1, UART_LCR1_INVTX_Msk, UART_LCR1_INVTX_Pos, state);
}

/*!
 * @brief Set UART Inverse the rx input
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] invRx: UART invRx.
 *                         -ENABLE: inverse rx input
 *                         -DISABLE: don't inverse rx input
 * @return none
 */
__STATIC_INLINE void UART_SetInvRx(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->LCR1, UART_LCR1_INVRX_Msk, UART_LCR1_INVRX_Pos, state);
}

/*!
 * @brief Set UART loop mode
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] Loop: UART loop
 *                         -ENABLE: loop mode
 *                         -DISABLE: normal mode
 * @return none
 */
__STATIC_INLINE void UART_SetLoop(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->LCR1, UART_LCR1_LOOP_Msk, UART_LCR1_LOOP_Pos, state);
}

/*!
 * @brief Set UART 2byte fifo enable
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] fifoByteEn: UART FIFO2ByteEn.
 *                         -ENABLE: enable both tx&rx fifo
 *                         -DISABLE: disable both tx&rx fifo
 * @return none
 */
__STATIC_INLINE void UART_Set2ByteFIFO(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->FCR, UART_FCR_FIFOE_Msk, UART_FCR_FIFOE_Pos, state);
}

/*!
 * @brief Set UART interrupt enable register, but doesnot set ETXE, ETC bit
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] interruptEn: UART interrupt enable
 * @return none
 */
__STATIC_INLINE void UART_SetInterruptEn(UART_Type *UARTx, uint16_t interruptEn)
{
    MODIFY_REG32(UARTx->IER, 0x1F9U, 0U, (interruptEn & 0x1F9U));  /* set interrupt, but doesnot set ETXE, ETC bit   */
}

/*!
 * @brief Set UART sleep enable
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] sleepEn: UART sleepEn.
 *                    -ENABLE: Activate hardware flow control according to software initial settings
 *                             when the chip enters the sleep mode. Release the hardware flow
 *                             when the chip wakes up.
 *                    -DISABLE: Does not deal with sleep mode indication signal
 * @return none
 */
__STATIC_INLINE void UART_SetSleepEn(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->SLEEP_EN, UART_SLEEP_EN_SLEEP_EN_Msk, UART_SLEEP_EN_SLEEP_EN_Pos, state);
}

/*!
 * @brief  Set UART DMA enable
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] dmaEn: UART DMA Enable set. value can be
 *                - UART_DMA_TXRX_NONE: both tx&rx transfer with normal mode
 *                - UART_DMA_RX_EN: rx with dma mode and tx with normal mode
 *                - UART_DMA_TX_EN: tx with dma mode and rx with normal mode
 *                - UART_DMA_TXRX_EN: both tx&rx transfer with dma mode
 * @return none
 */
__STATIC_INLINE void UART_EnableDMA(UART_Type *UARTx, UART_DmaEnType dmaEn)
{
    switch (dmaEn)
    {
    case UART_DMA_TXRX_NONE:         /* UART DMA TX and RX all disable */
        UARTx->DMA_EN &= ~UART_DMA_EN_RX_DMA_EN_Msk;
        UARTx->DMA_EN &= ~UART_DMA_EN_TX_DMA_EN_Msk;
        break;

    case UART_DMA_RX_EN:             /* UART DMA RX enable */
        UARTx->DMA_EN |= UART_DMA_EN_RX_DMA_EN_Msk;
        UARTx->DMA_EN &= ~UART_DMA_EN_TX_DMA_EN_Msk;
        break;

    case UART_DMA_TX_EN:             /* UART DMA TX enable */
        UARTx->DMA_EN &= ~UART_DMA_EN_RX_DMA_EN_Msk;
        UARTx->DMA_EN |= UART_DMA_EN_TX_DMA_EN_Msk;
        break;

    case UART_DMA_TXRX_EN:           /* UART DMA TX and RX all enable */
        UARTx->DMA_EN |= UART_DMA_EN_RX_DMA_EN_Msk;
        UARTx->DMA_EN |= UART_DMA_EN_TX_DMA_EN_Msk;
        break;

    default:
        break;
    }
}

/*!
 * @brief Set UART rs485 Control
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] rs485CR: UART RS485CR. the corresponding control bit means
 *                   - bit7: enable rs485 or disable
 *                   - bit5: inverse or don't inverse the polarity of rts_n
 *                   - bit4: delay insert between the last stop bit
 * @return none
 */
__STATIC_INLINE void UART_SetRS485CR(UART_Type *UARTx, uint8_t rs485CR)
{
    if (rs485CR & UART_RS485CR_DLYEN_Msk)  /* set DLYEN: bit4 */
    {
        UARTx->RS485CR |= UART_RS485CR_DLYEN_Msk;
    }
    else
    {
        UARTx->RS485CR &= ~UART_RS485CR_DLYEN_Msk;
    }

    if (rs485CR & UART_RS485CR_INVPOL_Msk)  /* set INVPOL: bit5 */
    {
        UARTx->RS485CR |= UART_RS485CR_INVPOL_Msk;
    }
    else
    {
        UARTx->RS485CR &= ~UART_RS485CR_INVPOL_Msk;
    }

    if (rs485CR & UART_RS485CR_RS485EN_Msk)  /* set RS485EN: bit7 */
    {
        UARTx->RS485CR |= UART_RS485CR_RS485EN_Msk;
    }
    else
    {
        UARTx->RS485CR &= ~UART_RS485CR_RS485EN_Msk;
    }
}

/*!
 * @brief Set UART delay time in RS485 mode
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] counter: UART Counter. value can be
 *                   - 7:0: 0~255 bits time for time delay in RS485 mode
 * @return none
 */
__STATIC_INLINE void UART_SetRS485Cnt(UART_Type *UARTx, uint8_t counter)
{
    UARTx->CNTR = counter;
}

/*!
 * @brief Set UART Idle line detect function enable.
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] state: UART Idle line detect function enable/disable
 *                         - ENABLE
 *                         - DISABLE
 * @return none
 */
__STATIC_INLINE void UART_SetIdleFuncEn(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->IDLE, UART_IDLE_ILEN_Msk, UART_IDLE_ILEN_Pos, state);
}

/*!
 * @brief Set UART idle interrupt enable.must set MULCOMEN=1
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] state: idle interrupt enable/disable
 *                         - ENABLE
 *                         - DISABLE
 * @return none
 */
__STATIC_INLINE void UART_SetIdleInterrupt(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->IDLE, UART_IDLE_IDLEIE_Msk, UART_IDLE_IDLEIE_Pos, state);
}

/*!
 * @brief Set UART Rx data is ready
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return mul com idle line detect
 */
#define UART_IsIdle(UARTx) ((uint32_t)(((UARTx)->LSR1 & UART_LSR1_IDLE_Msk) >> UART_LSR1_IDLE_Pos))

/*!
 * @brief Check if rx LIN sync error occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no occur, 1:occur
 */
#define UART_IsSyncError(UARTx) ((uint32_t)(((UARTx)->LSR1 & UART_LSR1_SYNERR_Msk) >> UART_LSR1_SYNERR_Pos))

/*!
 * @brief Check if rx LIN break occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no occur, 1:occur
 */
#define UART_IsBreak(UARTx) ((uint32_t)(((UARTx)->LSR1 & UART_LSR1_FBRK_Msk) >> UART_LSR1_FBRK_Pos))

/*!
 * @brief Check if cts change occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no occur, 1:occur
 */
#define UART_IsCtsChange(UARTx) ((uint32_t)(((UARTx)->LSR1 & UART_LSR1_DCTS_Msk) >> UART_LSR1_DCTS_Pos))

/*!
 * @brief Check if rx LIN break wakeup occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no occur, 1:occur
 */
#define UART_IsBreakWakeup(UARTx) ((uint32_t)(((UARTx)->LSR1 & UART_LSR1_LINWAK_Msk) >> UART_LSR1_LINWAK_Pos))

/*!
 * @brief Check if UART IDLE occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no occur, 1:occur
 */
#define UART_IsUartIdle(UARTx) ((uint32_t)(((UARTx)->LSR1 & UART_LSR1_UART_IDLE_Msk) >> UART_LSR1_UART_IDLE_Pos))

/*!
 * @brief Check if cts occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no occur, 1:occur
 */
#define UART_IsCts(UARTx) ((uint32_t)(((UARTx)->LSR1 & UART_LSR1_CTS_Msk) >> UART_LSR1_CTS_Pos))

/*!
 * @brief Check if rts occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no occur, 1:occur
 */
#define UART_IsRts(UARTx) ((uint32_t)(((UARTx)->LSR1 & UART_LSR1_RTS_Msk) >> UART_LSR1_RTS_Pos))

/*!
 * @brief Set UART LIN control
 *
 * @param[in] UARTx: UART type pointer
 * @param[in] linCtrl: UART linCtrl. the corresponding control bit means
 *                   - bit7: LIN Mode enable
 *                   - bit6: LIN Break character detect interrupt enable
 *                   - bit5: LIN Mode break detect length  1:11bits  0:10bits
 *                   - bit3: 1:0x55 used to auto baud rate detection  0: 0X55 not used to auto baud rate detection
 *                   - bit2: LIN sync byte error interrupt enable
 *                   - bit1: LIN wake up interrupt enable
 *
 * @return none
 */
__STATIC_INLINE void UART_SetLIN(UART_Type *UARTx, uint8_t linCtrl)
{
    MODIFY_REG32(UARTx->LINCR, 0xFEU, 0U, (linCtrl & 0xFEU));
}

/*!
 * @brief Set LIN sleep enable.
 *
 * @param[in] UARTx: UART type pointer
 * @param[in] enable: LIN sleep mode enable
 * @return none
 */
__STATIC_INLINE void UART_SetLINSleep(UART_Type *UARTx, ACTION_Type enable)
{
    MODIFY_REG32(UARTx->LINCR, UART_LINCR_LINSLP_Msk, UART_LINCR_LINSLP_Pos, enable);
}

/*!
 * @brief Get LIN sleep enable.
 *
 * @param[in] UARTx: UART type pointer
 * @return LIN sleep mode state
 */
__STATIC_INLINE uint8_t UART_GetLINSleepState(UART_Type *UARTx)
{
    return (UARTx->LINCR & UART_LINCR_LINSLP_Msk) >> UART_LINCR_LINSLP_Pos;
}

/*!
 * @brief Set LIN wakeup interrupt enable.
 *
 * @param[in] UARTx: UART type pointer
 * @param[in] enable: LIN wakeup enable
 * @return none
 */
__STATIC_INLINE void UART_SetLINWakeInt(UART_Type *UARTx, ACTION_Type enable)
{
    MODIFY_REG32(UARTx->LINCR, UART_LINCR_LINWAKIE_Msk, UART_LINCR_LINWAKIE_Pos, enable);
}

/*!
 * @brief Check if rx buffer get new data
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no date in buff or fifo,  1:RX buffer becoming full or RX FIFO not empty
 */
#define UART_RxIsDataReady(UARTx) ((uint32_t)(((UARTx)->LSR0 & UART_LSR0_DR_Msk) >> UART_LSR0_DR_Pos))

/*!
 * @brief Check if rx overflow error occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no error,  1:occur error
 */
#define UART_RxIsOverflowError(UARTx) ((uint32_t)(((UARTx)->LSR0 & UART_LSR0_OE_Msk) >> UART_LSR0_OE_Pos))

/*!
 * @brief Check if rx parity error occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no error,  1:occur error
 */
#define UART_RxIsParityError(UARTx) ((uint32_t)(((UARTx)->LSR0 & UART_LSR0_PE_Msk) >> UART_LSR0_PE_Pos))

/*!
 * @brief Check if rx frame error occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no error,  1:occur error
 */
#define UART_RxIsFrameError(UARTx) ((uint32_t)(((UARTx)->LSR0 & UART_LSR0_FE_Msk) >> UART_LSR0_FE_Pos))

/*!
 * @brief Check if rx break error occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no error,  1:occur error
 */
#define UART_RxIsBreakError(UARTx) ((uint32_t)(((UARTx)->LSR0 & UART_LSR0_BI_Msk) >> UART_LSR0_BI_Pos))

/*!
 * @brief Check if rx noise error occur
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:no error,  1:occur error
 */
#define UART_RxIsNoiseError(UARTx) ((uint32_t)(((UARTx)->LSR0 & UART_LSR0_NE_Msk) >> UART_LSR0_NE_Pos))

/*!
 * @brief Set UART Tx buffer is empty
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 0:TX holding register or FIFO is not empty   1:TX holding register or FIFO is empty
 */
#define UART_TxIsEmpty(UARTx) ((uint32_t)(((UARTx)->LSR0 & UART_LSR0_THRE_Msk) >> UART_LSR0_THRE_Pos))

/*!
 * @brief Set UART Tx buffer is empty
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return Tx is full or not:
 *                         0:TX holding register or FIFO is not empty
 *                         1:TX holding register or FIFO is empty
 */
#define UART_TxIsFull(UARTx) ((uint32_t)(((UARTx)->LSR0 & UART_LSR0_TXDF_Msk) >> UART_LSR0_TXDF_Pos))

/*!
 * @brief Get UART Tx Finished or not
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return Tx tranfer has finished nor not
 *                         0:transmitter has not finished
 *                         1:transmitter has finished
 */
#define UART_TxIsFinished(UARTx) ((uint32_t)(((UARTx)->LSR0 & UART_LSR0_TC_Msk) >> UART_LSR0_TC_Pos))

/*!
 * @brief Enable UART TX
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] Enable/Disable UART tx
 *                         - ENABLE
 *                         - DISABLE
 * @return none
 */
__STATIC_INLINE void UART_EnableTX(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->LCR1, UART_LCR1_TXEN_Msk, UART_LCR1_TXEN_Pos, state);
}

/*!
 * @brief Enable UART RX
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] Enable/Disable UART rx
 *                         - ENABLE
 *                         - DISABLE
 * @return none
 */
__STATIC_INLINE void UART_EnableRX(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->LCR1, UART_LCR1_RXEN_Msk, UART_LCR1_RXEN_Pos, state);
}

/*!
 * @brief Send lin break
 *
 * @param[in] UARTx: UART type pointer
 * @return none
 */
__STATIC_INLINE void UART_SendLINBreak(UART_Type *UARTx)
{
    UARTx->LINCR |= UART_LINCR_SDBRK_Msk;
}

/*!
 * @brief Lin break length for master
 *
 * @param[in] UARTx: UART type pointer
 * @param[in] length:LIN break length
 * @return none
 */
__STATIC_INLINE void UART_SetLINBreakLength(UART_Type *UARTx, uint8_t length)
{
    UARTx->BRKLGH = (length & UART_BRKLGH_BRKLGH_Msk);
}

/*!
 * @brief Enable rx buffer not empty interrupt
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] Enable/Disable Rx not empty interrupt
 *                         - ENABLE
 *                         - DISABLE
 * @return none
 */
__STATIC_INLINE void UART_SetRXNEInterrupt(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->IER, UART_IER_ERXNE_Msk, UART_IER_ERXNE_Pos, state);
}

/*!
 * @brief Enable tx holding register is empty interrupt
 *
 * @param[in] UARTx: UART type pointer, x can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @param[in] Enable/Disable Tx empty interrupt
 *                         - ENABLE
 *                         - DISABLE
 */
__STATIC_INLINE void UART_SetTXEInterrupt(UART_Type *UARTx, ACTION_Type state)
{
    MODIFY_REG32(UARTx->IER, UART_IER_ETXE_Msk, UART_IER_ETXE_Pos, state);
}

/*!
 * @brief Check UART Data Bits is 9 bits or not
 *
 * @param[in] UARTx: UART type pointer, x value can be 0 to 2
 *                         - UART0
 *                         - UART1
 *                         - UART2
 * @return 1: 9 bits
 *         0: 5~8 bits
 */
__STATIC_INLINE uint8_t UART_IsNineDataBits(UART_Type *UARTx)
{
    return (uint8_t)(((UARTx->LCR1 & UART_LCR1_WLS2_Msk) >> UART_LCR1_WLS2_Pos));
}

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _AC780X_UART_REG_H */

/* =============================================  EOF  ============================================== */
